<?php

namespace api\power;

use app\common\model\Power;
use think\facade\Db;

/**
 * 微客云电费.
 */
class Wikeyun
{
    private $id = 0;
    private $appKey = '';
    private $appSecret = '';
    private $url = '';
    private $storeId = '';
    private $error = '';
    private $header = [
        'Content-Type: application/json',
    ];

    public function __construct($info)
    {
        $this->id = $info['id'];
        $config = json_decode($info['api_config'], true);
        $this->appKey = $config['app_id'];
        $this->appSecret = $config['app_secret'];
        $this->url = $config['url'];
        $this->storeId = $config['store_id'];
    }

    /**
     * 添加充值卡
     */
    public function addCard($data)
    {
        $url = $this->url.'/rest/Power/addCard?';
        $params = [
            'store_id' => $this->storeId,
            'card_num' => $data['card_no'],
            'province' => str_replace('省', '', $data['province']),
            'city' => str_replace('省', '', $data['city']),
            'remark' => $data['remark'] ?? '',
            'type' => $data['type'],
        ];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，返回'.$res);
        }
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 获取微客云 card_id
     */
    public function getCardId($card)
    {
        $cardId = Db::name('power_card')
            ->where('card_no', $card['card_no'])
            ->where('type', $card['type'])
            ->value('card_id');
        if ($cardId) {
            return $cardId;
        }

        $res = $this->addCard($card);
        if (!isset($res['code']) || $res['code'] != '0000') {
            $this->error = $res['msg'] ?? '添加油卡失败';
            return false;
        }

        Db::name('power_card')
            ->insert([
                'card_no' => $card['card_no'],
                'province' => $card['province'],
                'city' => $card['city'],
                'type' => $card['type'],
                'card_id' => $res['data']['id'],
            ]);
        return $res['data']['id'];
    }

    /**
     * 编辑充值卡
     */
    public function editCard($data)
    {
        $url = $this->url.'/rest/Power/editCard?';
        $params = [
            'card_id' => $data['card_id'],
            'card_num' => $data['card_no'],
            'province' => str_replace('省', '', $data['province']),
            'city' => str_replace('省', '', $data['city']),
            'remark' => $data['remark'] ?? '',
            'type' => $data['type'],
        ];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，返回'.$res);
        }
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 删除充值卡
     */
    public function delCard($data)
    {
        $url = $this->url.'/rest/Power/delCard?';
        $params = [
            'card_id' => $data['card_id'],
        ];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，返回'.$res);
        }
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 充值卡详情.
     */
    public function cardInfo($data)
    {
        $url = $this->url.'/rest/Power/cardInfo?';
        $params = [
            'card_id' => $data['card_id'],
        ];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，返回'.$res);
        }
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 创建订单.
     *
     * @params
     * sub_order_id 系统订单号
     * amount 充值金额
     * mobile 充值号码
     */
    public function create($order)
    {
        $cardId = $this->getCardId([
            'card_no' => $order['card_no'],
            'province' => $order['province'],
            'city' => $order['city'],
            'remark' => '',
            'type' => $order['card_type'],
        ]);
        if (false === $cardId) {
            return ['code' => 0, 'msg' => '添加充值卡失败: ' . $this->error];
        }

        $url = $this->url.'/rest/Power/pushOrder?';
        $params = [
            'store_id' => $this->storeId,
            'cardId' => $cardId,
            'order_no' => $order['sub_order_id'],
            'amount' => fen2yuan($order['amount']),
            'recharge_type' => 1 == $order['order_type'] ? 0 : 1,
            'notify_url' => env('app.api_url').'/api/PowerNotify/wikeyun',
        ];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，params: '.json_encode($params, JSON_UNESCAPED_UNICODE).',返回'.$res);
        }
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 查询余额.
     *
     * 单位：分
     */
    public function queryAmount()
    {
        $url = $this->url.'/rest/User/query?';
        $params = [];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，返回'.$res);
        }
        $res = json_decode($res, true);
        if (!isset($res['data']['money'])) {
            $this->error = $res['msg'] ?? '查询频繁';

            return false;
        }

        return yuan2fen($res['data']['money']);
    }

    /**
     * 订单查询.
     */
    public function query($orderId)
    {
        $url = $this->url.'/rest/Power/query?';
        $params = [
            'order_number' => $orderId,
        ];
        $systemParams = $this->getSystemParams();
        $systemParams['sign'] = $this->getSign(array_merge($params, $systemParams));
        $url .= http_build_query($systemParams);
        $res = curlPost($url, json_encode($params), $this->header);
        // 日志记录
        if (function_exists('doLog')) {
            doLog('微客云电费请求日志，'.$url.'，返回'.$res);
        }
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 生成签名.
     */
    public function getSign($params)
    {
        if (isset($params['sign'])) {
            unset($params['sign']);
        }
        ksort($params);
        $str = $this->appSecret;
        foreach ($params as $k => $v) {
            $str .= $k.$v;
        }
        $str .= $this->appSecret;

        return strtoupper(md5($str));
    }

    /**
     * 订单回调.
     */
    public function notify($params)
    {
        $insert = [
            'sub_order_id' => $params['order_no'] ?? '',
            'params' => json_encode($params, JSON_UNESCAPED_UNICODE),
            'result' => 'success',
        ];

        // $sign = $params['sign'] ?? '';
        // $checkSign = $this->getSign($params);
        // if ($sign !== $checkSign) {
        //     $insert['result'] = '验签失败';
        //     Db::name('power_notify')->insert($insert);
        //     return $insert['result'];
        // }

        $order = Db::name('power_order')
            ->where('sub_order_id', $params['order_no'])
            ->where('supplier_id', $this->id)
            ->find();
        if (empty($order)) {
            $insert['result'] = '订单不存在';
            Db::name('power_notify')->insert($insert);

            return $insert['result'];
        }

        if (3 == $order['supplier_status']) {
            $insert['result'] = '已经成功过';
            Db::name('power_notify')->insert($insert);

            return 'success';
        }

        if (2 != $order['supplier_status']) {
            $insert['result'] = '订单状态有误：'.$order['supplier_status'];
            Db::name('power_notify')->insert($insert);

            return $insert['result'];
        }

        // 供应商订单状态：1订单未创建 2订单已创建 3充值成功 4充值失败 99充值失败，等待重试
        // 交易结果（0 待支付 1 已付 充值中 2充 值成功 3充值失败 需要退款 4退款成功 6 待充值 7 已匹配）
        $supplierStatusMap = [
            0 => 2,
            1 => 2,
            2 => 3,
            3 => 4,
            4 => 4,
            6 => 2,
            7 => 2,
        ];
        $supplierStatus = $supplierStatusMap[$params['status']] ?? 2;
        if ($order['supplier_status'] == $supplierStatus) {
            Db::name('power_notify')->insert($insert);

            return 'success';
        }
        $update = [
            'supplier_order_no' => $params['order_number'],
            'supplier_status' => $supplierStatus,
        ];
        if (in_array($supplierStatus, [3, 4])) {
            $update['finish_time'] = time();
        } else {
            $order['notify_url'] = '';
        }
        if (4 == $supplierStatus) {
            $update['refund_status'] = 2;
        }
        // if ($supplierStatus == 99) {
        //     $order['notify_url'] = '';  // 失败通知先不发
        // }

        Db::name('power_notify')->insert($insert);

        Db::startTrans();
        try {
            // 如果是返佣模式，将订单结算方式改成待结算
            if (3 == $supplierStatus && SETTLE_TYPE_PROFIT == $order['settle_type']) {
                if (0 == $order['profit']) {
                    $update['settle_status'] = 3;
                } elseif (1 == $order['settle_status']) {
                    $update['settle_status'] = 2;
                }
            }

            Power::handleNotify($order, $update);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            $insert['result'] = '订单更新失败'.$order['id'].'。'.$e->getMessage();
            Db::name('power_notify')->insert($insert);

            return $insert['result'];
        }

        return 'success';
    }

    public function getSystemParams()
    {
        return [
            'app_key' => $this->appKey,
            'timestamp' => time(),
            'client' => '127.0.0.1',
            'v' => '1.0',
            'format' => 'json',
        ];
    }

    public function getError()
    {
        return $this->error;
    }
}
